package br.ufpe.cin.mac.middleware.components;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;

import br.ufpe.cin.mac.middleware.ports.inputports.components.InvP;
import br.ufpe.cin.mac.middleware.ports.inputports.components.TerU;
import br.ufpe.cin.mac.middleware.ports.outputports.components.InvU;
import br.ufpe.cin.mac.middleware.ports.outputports.components.TerP;
import br.ufpe.cin.mac.util.Constants;
import br.ufpe.cin.mac.util.Message;

public abstract class Component extends NotificationBroadcasterSupport {

	protected long seq;

	protected final String componentName;

	protected Map<Integer,Message> buffer;

	protected InvU invU;
	
	protected InvP invP;
	
	protected TerP terP;
	
	protected TerU terU;
	
	public Component(String name) {
		this.componentName = name;
		this.buffer = Collections.synchronizedMap(new HashMap<Integer,Message>());
	}

	public void invP(final Message msg) {
		new Thread() {
			public void run() {
				msgManager(msg);
			}
		}.start();
	}

	public Message invU(int hashMsg) {
		return (Message) this.buffer.remove(hashMsg);
	}

	public Message terP(int hashMsg) {
		return (Message) this.buffer.remove(hashMsg);
	}

	public void terU(final Message msg) {
		new Thread() {
			public void run() {
				msgManager(msg);
			}
		}.start();
	}

	protected abstract void msgManager(Message msg);

	protected void sendNotification(Message msg, String port) {
		Notification not = new Notification(getCanonicalName()
				+ ":" + port, this, this.seq++);
		not.setUserData(msg.hashCode());
		sendNotification(not);
	}
	
	public String getCanonicalName() {
		String component = componentName.replace(".",":");
		String[] split = component.split(":");
		
		return split[split.length-1];
	}
}
